Sissejuhatus

Tänaes praktikum on esimene kahest, kus vaatame kaardiandmeid. Me kasutame kaardiandmete jaoks simple features formaati mida R-s implementeerib pakett nimega sf. Loeme sisse ka paketi osmdata, millega vaatame pärastpoole kuidas tõmmata Open Street Maps kaardiinfot.

library(sf)
Linking to GEOS 3.8.1, GDAL 3.1.4, PROJ 6.3.1
library(osmdata)
Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(tidyverse)
library(ggspatial)
library(rnaturalearth)
library(rgeos)
Loading required package: sp
rgeos version: 0.5-5, (SVN revision 640)
 GEOS runtime version: 3.8.1-CAPI-1.13.3 
 Linking to sp version: 1.4-2 
 Polygon checking: TRUE 

Kaardiandmed ja nende näitamine

Näidisandmestikuna kasutame Eesti maakondade ja valdade andmestikku.

load("eesti.RData", verbose = T)
Loading objects:
  vald
  maakond
  eesti

Need andmed on formaadis sf, mis on sisuliselt andmetabel, kus on üks veerg (tavaliselt nimdega geometry) milles hoitakse vektorkujul objekti esitust. Lisaks on sellele tabelil eraldi päis mis hoiab informatsiooni andmete tüübi, asukoha ja projektsiooni kohta.

maakond
Simple feature collection with 15 features and 2 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 369548.2 ymin: 6377146 xmax: 739149.6 ymax: 6617809
Projected CRS: Estonian Coordinate System of 1997
First 10 features:
              MNIMI MKOOD                       geometry
1     Saare maakond  0074 MULTIPOLYGON (((454431 6409...
2  Viljandi maakond  0084 MULTIPOLYGON (((621348.6 64...
3      Hiiu maakond  0039 MULTIPOLYGON (((449832.4 65...
4     Harju maakond  0037 MULTIPOLYGON (((497565 6580...
5     Lääne maakond  0056 MULTIPOLYGON (((462065.5 65...
6     Rapla maakond  0071 MULTIPOLYGON (((509334.5 65...
7  Ida-Viru maakond  0045 MULTIPOLYGON (((716681.5 65...
8     Valga maakond  0081 MULTIPOLYGON (((622099.9 64...
9     Tartu maakond  0079 MULTIPOLYGON (((705560 6477...
10    Järva maakond  0052 MULTIPOLYGON (((576673.2 65...

Tunnus geometry võib olla kujul POINT, LINE, POLYGON, MULTIPOINT, MULTILINE ja MULTIPOLYGON. Iga sf objekt sisaldab vaid ühte tüüpi geometry elemente. MULTIPOLYGON tähendab, et tegemist on kaheväärtuselise tulbaga, mille väärtused määravad hulknurga küljed.

Sisuliselt saab sellele andmetabelil teha kõiki operatsioone, mida me saame teha tavalise andmetabeliga.

vald %>% 
  mutate(Linn = str_detect(ONIMI, "linn"))
Simple feature collection with 79 features and 6 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 369548.2 ymin: 6377146 xmax: 739149.6 ymax: 6633918
Projected CRS: Estonian Coordinate System of 1997
First 10 features:
           ONIMI OKOOD            MNIMI MKOOD TYYP                       geometry  Linn
1     Ruhnu vald  0689    Saare maakond  0074    1 MULTIPOLYGON (((454431 6409... FALSE
2      Muhu vald  0478    Saare maakond  0074    1 MULTIPOLYGON (((463418.4 64... FALSE
3    Viimsi vald  0890    Harju maakond  0037    1 MULTIPOLYGON (((544438.3 66... FALSE
4  Saaremaa vald  0714    Saare maakond  0074    1 MULTIPOLYGON (((395602.3 64... FALSE
5   Hiiumaa vald  0205     Hiiu maakond  0039    1 MULTIPOLYGON (((449832.4 65... FALSE
6     Kihnu vald  0303    Pärnu maakond  0068    1 MULTIPOLYGON (((500160.5 64... FALSE
7    Vormsi vald  0907    Lääne maakond  0056    1 MULTIPOLYGON (((458345.9 65... FALSE
8  Viljandi linn  0897 Viljandi maakond  0084    4 MULTIPOLYGON (((591276.3 64...  TRUE
9     Kiili vald  0305    Harju maakond  0037    1 MULTIPOLYGON (((543644.9 65... FALSE
10       Tallinn  0784    Harju maakond  0037    4 MULTIPOLYGON (((544048.5 66...  TRUE
vald %>% 
  filter(MNIMI == "Saare maakond")
Simple feature collection with 3 features and 5 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 369548.2 ymin: 6404515 xmax: 467694.4 ymax: 6505176
Projected CRS: Estonian Coordinate System of 1997
          ONIMI OKOOD         MNIMI MKOOD TYYP                       geometry
1    Ruhnu vald  0689 Saare maakond  0074    1 MULTIPOLYGON (((454431 6409...
2     Muhu vald  0478 Saare maakond  0074    1 MULTIPOLYGON (((463418.4 64...
3 Saaremaa vald  0714 Saare maakond  0074    1 MULTIPOLYGON (((395602.3 64...

Andmeid sf formaadis saab visualiseerida ggplot2-ga. Selleks on olemas eraldi funktsioon geom_sf.

ggplot(maakond) +
  geom_sf()


ggplot(maakond) +
  geom_sf(color = "orange", fill = "lightblue")

Erinevatel kihtidel saab näidata erinevaid andmestikke.

ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf(color = "orange", data = vald %>% filter(MNIMI == "Harju maakond")) 

Et geograafilisi andmeid saaks parmeini sildistada on loodud funktsioonid geom_sf_label ja geom_sf_text. Saame kasutada ainult geom_sf_…., sest meil pole x ja y koordinaate ja masin üritab sildi panna lihtsalt objekti (maakond) keskele

ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_label(aes(label = MNIMI))


ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_text(aes(label = MNIMI))

Kasutades sama süntaksit nagu me rakendasime võrgustike puhul saame me ka siin siltide arvu vähendada, võttes andmestikust alamhulki.

ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_label(aes(label = MNIMI), data = ~ .x %>% filter(MNIMI %in% c("Hiiu maakond", "Saare maakond"))) 

Loomulikult saab pildil muuta ka tausta ja väljanägemist kasutades theme_* funktsioone. Nagu võrgustikegi puhul, on theme_void hea valik, et puhtamaid pilte saada. Kuid ka muud funktsioonid, näiteks theme_bw, töötavad. Meil pole enamasti vaja teada, mis need koordinaadid on täpselt. Sellep on theme_void hea ka.

ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_label(aes(label = MNIMI), data = ~ .x %>% filter(MNIMI %in% c("Hiiu maakond", "Saare maakond"))) +
  theme_bw()


ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_label(aes(label = MNIMI), data = ~ .x %>% filter(MNIMI %in% c("Hiiu maakond", "Saare maakond"))) +
  theme_void()

Et kaart oleks efektsem võib muuta ka muid parameetreid. Näiteks kaardid tumedal taustal näevad tihti välja väga pilkupüüdvad.

ggplot(maakond) +
  geom_sf(fill = NA, color = "white") +
  theme_void() +
  theme(plot.background = element_rect(fill = "black"))

Kaartidele lisatakse tihti ka mõõtkava ja nooleke mis näitab kus suunas on põhi. Ka meie joonistatud graafikutel on see võimalik, kasutades paketti ggspatial, ning sealt funktsioone annotation_scale ja annotation_north_arrow. pad_y tõstab noolekest ülespoole

ggplot(maakond) +
  geom_sf(fill = "lightblue") +
  geom_sf_label(aes(label = MNIMI), data = ~ .x %>% filter(MNIMI %in% c("Hiiu maakond", "Saare maakond"))) +
  annotation_scale(location = "bl", width_hint = 0.3) +
  annotation_north_arrow(location = "bl", pad_y = unit(0.3, "in"), style = north_arrow_fancy_orienteering()) +
  theme_void()

Ülesanne

  • Joonista kaart Harjumaa valdadest (heledamat värvi taustaga) ning lisa sellele Tallinn tumedama taustaga. Tallinna juurde pane ka silt linna nimega. Eemaldage pildidlt ka kõik teljed ja muu ning lisage üles vasakusse nurka skaala ja põhjasuunaline nool.
vald %>% 
  filter(MNIMI == "Harju maakond") %>% 
  ggplot() +
  geom_sf(fill = "lightblue") +
  geom_sf(fill = "darkblue", data = ~.x %>% filter(ONIMI == "Tallinn"))+
  geom_sf_label(aes(label = ONIMI), data = ~ .x %>% filter(ONIMI == "Tallinn")) +
  annotation_scale(location = "tl", width_hint = 0.3) +
  annotation_north_arrow(location = "tl", pad_y = unit(0.3, "in"), style = north_arrow_fancy_orienteering()) +
  theme_void()

Värvitud kaardid

Üks levinumaid kaartide kasutusalasid andmeteaduses on mingi tunnuse järgi värvitud kaardid (i.k cloropeth maps). Eelneva põhjal pole väga raske arvata kuidas nende joonistamine võib käia, kuna saame kasutada sarnaseid ggplot2 nippe nagu eelnevateski praktikumides. Enne aga kui läheme kaartide joonistamise juurde loeme sisse andmestiku, mis kirjeldab koroonavaktsineerimise hetkeseisu vanusegruppides ja soo kaupa kuupäva 18/03/2021 seisuga.

load("vaktsiin.RData", verbose = T)
Loading objects:
  vaktsiin
vaktsiin

Selleks, et meil tekiks lihtsam andmestik mida uurida summeerime arvud maakonna kaupa.

v = vaktsiin %>% 
  group_by(County) %>% 
  summarize(
    TotalCount = sum(TotalCount),
    TotalPopulation = sum(Population)
  ) 

v

Nüüd saame selle andmestiku liita olemasolevale maakonna andmestikule. Selleks otstarbeks saab kasutada *_join perekonna käskusid. Need on analoogsed SQL join käskudega ja sinna perekonda kuuluvad.

Ühendamine käib vaikimis tunnuste alusel millel on sama nimi. Ühendame nüüd tabelid v ja maakond. Pane tähele, et tasub ühedada andmed sf objekti külge mitte vastupidi, sest muidu muutub objekti tüüp.

#Muudame nime, et joini tulp oleks sama nimega (MNIMI)
vm = maakond %>% 
  left_join(v %>% rename(MNIMI = County))
Joining, by = "MNIMI"
vm
Simple feature collection with 15 features and 4 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 369548.2 ymin: 6377146 xmax: 739149.6 ymax: 6617809
Projected CRS: Estonian Coordinate System of 1997
First 10 features:
              MNIMI MKOOD TotalCount TotalPopulation                       geometry
1     Saare maakond  0074       6773           29525 MULTIPOLYGON (((454431 6409...
2  Viljandi maakond  0084       8493           45098 MULTIPOLYGON (((621348.6 64...
3      Hiiu maakond  0039       2117            8451 MULTIPOLYGON (((449832.4 65...
4     Harju maakond  0037      88409          594737 MULTIPOLYGON (((497565 6580...
5     Lääne maakond  0056       4377           21475 MULTIPOLYGON (((462065.5 65...
6     Rapla maakond  0071       6447           29300 MULTIPOLYGON (((509334.5 65...
7  Ida-Viru maakond  0045      12183          138259 MULTIPOLYGON (((716681.5 65...
8     Valga maakond  0081       4604           26639 MULTIPOLYGON (((622099.9 64...
9     Tartu maakond  0079      29405          149246 MULTIPOLYGON (((705560 6477...
10    Järva maakond  0052       5750           29008 MULTIPOLYGON (((576673.2 65...
#Kui nii teeme, nagu siin, siis saab tulemuseks dataframe ja ei saa kasutada kaardi pakette
v %>% 
  rename(MNIMI = County) %>% 
  left_join(maakond)
Joining, by = "MNIMI"

Nüüd saame joonistada kaardi mis on värvitud vaktsineerimiste arvu järgi.

#Vaktsineeritute osakaal kogu maaskonna rahvastikust
ggplot(vm) + 
  geom_sf(aes(fill = TotalCount/TotalPopulation))

Seda pilti saab modifitseerida kasutades ggplot2-st tuttavaid võtteid.

#Lisame sildi, muudame gradienti värvi ja kaotame teljed ära.
ggplot(vm) + 
  geom_sf(aes(fill = TotalCount/TotalPopulation)) +
  geom_sf_text(aes(label = round(TotalCount/TotalPopulation, 3)), color = "white") +
  scale_fill_gradient("PropVaccinated", low = "lightgreen", high = "darkgreen") +
  theme_void()

NA

Andmetabelite ühendamisel peab olema ettevaatlik joiniga, et meie read ei paljuneks. Kui sama maakonna kohta on mitu andmepunkti, siis maakondade tabeli ridu paljundatakse nii palju, et ridade arv klapiks teise andmestikuga. Sellep leidsime alguses TotalCounti jms summeeritud tabeli, kuna vaktsiin tabelis on igas maakonnas erinevate vanusegruppide read jms. Seega igal maakonnal mitu rida.


maakond %>% 
  left_join(vaktsiin %>% rename(MNIMI = County)) %>% 
  ggplot() +
   geom_sf(aes(fill = TotalCount))
Joining, by = "MNIMI"

Ülesanne

  • Joonista värvitud kaart graafik grupi “üle 70” (M +N), vaktsineeritute protsendi kohta.
v2 = vaktsiin %>%
  filter(AgeGroup == "üle 70") %>% 
  group_by(County) %>% 
  summarize(
    TotalCount = sum(TotalCount),
    TotalPopulation = sum(Population)
  ) 

v2

vm2 = maakond %>% 
  left_join(v2 %>% rename(MNIMI = County))
Joining, by = "MNIMI"
ggplot(vm2) + 
  geom_sf(aes(fill = TotalCount/TotalPopulation)) +
  geom_sf_text(aes(label = round(TotalCount/TotalPopulation, 3)), color = "white") +
  scale_fill_gradient("PropVaccinated", low = "lightgreen", high = "darkgreen") +
  theme_void()

Geograafiliste andmete leidmine

Maaameti Geoportaal

Eesti kohta on palju avaandmeid saadaval Maaameti Geoportaalis. Vektorkujul andmetele viidatakse, kui SHP formaadis andmetele. Vaatame näiteks lehele https://geoportaal.maaamet.ee/est/Ruumiandmed/Eesti-topograafia-andmekogu/Laadi-ETAK-andmed-alla-p609.html

Ja laeme sealt alla SHP faili tehnovõrkude kohta.

tehno = st_read("ETAK_Eesti_SHP_tehnovorgud/E_601_elektriliin_j.shp")
Reading layer `E_601_elektriliin_j' from data source `/Users/siimpoldre/Documents/r_projects/ut_andmeviz/ETAK_Eesti_SHP_tehnovorgud/E_601_elektriliin_j.shp' using driver `ESRI Shapefile'
Simple feature collection with 17381 features and 14 fields
Geometry type: LINESTRING
Dimension:     XYZ
Bounding box:  xmin: 372179.3 ymin: 6381269 xmax: 739366 ymax: 6614243
z_range:       zmin: 0 zmax: 286.931
Projected CRS: Estonian Coordinate System of 1997
tehno
Simple feature collection with 17381 features and 14 fields
Geometry type: LINESTRING
Dimension:     XYZ
Bounding box:  xmin: 372179.3 ymin: 6381269 xmax: 739366 ymax: 6614243
z_range:       zmin: 0 zmax: 286.931
Projected CRS: Estonian Coordinate System of 1997
First 10 features:
   etak_id kood      kood_t nimipinge ehr_gid markused vajalik vajalik_t andmeallik korgusalli ruumikujua muutmisaeg geom_muutm  valjavote
1  4489256  601 Elektriliin        NA    <NA>     <NA>      30    Korras        216        216        216 2020-12-08 2020-12-08 2021-03-27
2  4489271  601 Elektriliin        NA    <NA>     <NA>      30    Korras        216        216        216 2020-12-08 2020-12-08 2021-03-27
3  4502202  601 Elektriliin        NA    <NA>     <NA>      30    Korras        206        206        206 2018-04-13 2018-04-13 2021-03-27
4  4488814  601 Elektriliin        NA    <NA>     <NA>      30    Korras        216        216        216 2020-12-08 2020-12-08 2021-03-27
5  8259796  601 Elektriliin        10    <NA>     <NA>      30    Korras        218        999        218 2020-12-09 2020-12-09 2021-03-27
6  8259790  601 Elektriliin        10    <NA>     <NA>      30    Korras        218        999        218 2020-12-09 2020-12-09 2021-03-27
7  5231961  601 Elektriliin        NA    <NA>     <NA>      30    Korras        206        206        206 2018-01-09 2018-01-09 2021-03-27
8  4503269  601 Elektriliin        NA    <NA>     <NA>      30    Korras        206        206        206 2018-05-31 2018-05-31 2021-03-27
9  4506099  601 Elektriliin        NA    <NA>     <NA>      30    Korras        214        214        214 2018-12-07 2018-12-07 2021-03-27
10 4492158  601 Elektriliin        10    <NA>     <NA>      30    Korras        219        219        219 2021-02-09 2021-02-09 2021-03-27
                         geometry
1  LINESTRING Z (697152.3 6416...
2  LINESTRING Z (697152.3 6416...
3  LINESTRING Z (583845.2 6491...
4  LINESTRING Z (691071.5 6416...
5  LINESTRING Z (575686.3 6575...
6  LINESTRING Z (577202.3 6574...
7  LINESTRING Z (705681.4 6408...
8  LINESTRING Z (585793.8 6490...
9  LINESTRING Z (596968.9 6513...
10 LINESTRING Z (416809.9 6509...
tehno %>% 
  ggplot() +
    geom_sf()

Natural Earth

Kui me tahame joonistada suuremaid kaarte kui Eesti kohta, näiteks maailmajao või maailma tasemel, siis on heaks allikaks Natural Earth andmebaas, kus on maailma riikide kohta käiv statistika ja nende kujufailid mugavalt kokku pandud. R-s saab sinna ligi paketiga rnaturalearth ning selle funktsiooniga ne_countires.

countries = ne_countries(returnclass = "sf")

countries
Simple feature collection with 177 features and 63 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: -180 ymin: -90 xmax: 180 ymax: 83.64513
CRS:           +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
First 10 features:
  scalerank      featurecla labelrank           sovereignt sov_a3 adm0_dif level              type                               admin adm0_a3
0         1 Admin-0 country         3          Afghanistan    AFG        0     2 Sovereign country                         Afghanistan     AFG
1         1 Admin-0 country         3               Angola    AGO        0     2 Sovereign country                              Angola     AGO
2         1 Admin-0 country         6              Albania    ALB        0     2 Sovereign country                             Albania     ALB
3         1 Admin-0 country         4 United Arab Emirates    ARE        0     2 Sovereign country                United Arab Emirates     ARE
4         1 Admin-0 country         2            Argentina    ARG        0     2 Sovereign country                           Argentina     ARG
5         1 Admin-0 country         6              Armenia    ARM        0     2 Sovereign country                             Armenia     ARM
6         1 Admin-0 country         4           Antarctica    ATA        0     2     Indeterminate                          Antarctica     ATA
7         3 Admin-0 country         6               France    FR1        1     2        Dependency French Southern and Antarctic Lands     ATF
8         1 Admin-0 country         2            Australia    AU1        1     2           Country                           Australia     AUS
9         1 Admin-0 country         4              Austria    AUT        0     2 Sovereign country                             Austria     AUT
  geou_dif                             geounit gu_a3 su_dif                             subunit su_a3 brk_diff                   name
0        0                         Afghanistan   AFG      0                         Afghanistan   AFG        0            Afghanistan
1        0                              Angola   AGO      0                              Angola   AGO        0                 Angola
2        0                             Albania   ALB      0                             Albania   ALB        0                Albania
3        0                United Arab Emirates   ARE      0                United Arab Emirates   ARE        0   United Arab Emirates
4        0                           Argentina   ARG      0                           Argentina   ARG        0              Argentina
5        0                             Armenia   ARM      0                             Armenia   ARM        0                Armenia
6        0                          Antarctica   ATA      0                          Antarctica   ATA        0             Antarctica
7        0 French Southern and Antarctic Lands   ATF      0 French Southern and Antarctic Lands   ATF        0 Fr. S. Antarctic Lands
8        0                           Australia   AUS      0                           Australia   AUS        0              Australia
9        0                             Austria   AUT      0                             Austria   AUT        0                Austria
                            name_long brk_a3                   brk_name brk_group     abbrev postal
0                         Afghanistan    AFG                Afghanistan      <NA>       Afg.     AF
1                              Angola    AGO                     Angola      <NA>       Ang.     AO
2                             Albania    ALB                    Albania      <NA>       Alb.     AL
3                United Arab Emirates    ARE       United Arab Emirates      <NA>     U.A.E.     AE
4                           Argentina    ARG                  Argentina      <NA>       Arg.     AR
5                             Armenia    ARM                    Armenia      <NA>       Arm.    ARM
6                          Antarctica    ATA                 Antarctica      <NA>       Ant.     AQ
7 French Southern and Antarctic Lands    ATF Fr. S. and Antarctic Lands      <NA> Fr. S.A.L.     TF
8                           Australia    AUS                  Australia      <NA>       Auz.     AU
9                             Austria    AUT                    Austria      <NA>      Aust.      A
                                             formal_en formal_fr note_adm0                         note_brk                           name_sort
0                         Islamic State of Afghanistan      <NA>      <NA>                             <NA>                         Afghanistan
1                          People's Republic of Angola      <NA>      <NA>                             <NA>                              Angola
2                                  Republic of Albania      <NA>      <NA>                             <NA>                             Albania
3                                 United Arab Emirates      <NA>      <NA>                             <NA>                United Arab Emirates
4                                   Argentine Republic      <NA>      <NA>                             <NA>                           Argentina
5                                  Republic of Armenia      <NA>      <NA>                             <NA>                             Armenia
6                                                 <NA>      <NA>      <NA> Multiple claims held in abeyance                          Antarctica
7 Territory of the French Southern and Antarctic Lands      <NA>       Fr.                             <NA> French Southern and Antarctic Lands
8                            Commonwealth of Australia      <NA>      <NA>                             <NA>                           Australia
9                                  Republic of Austria      <NA>      <NA>                             <NA>                             Austria
  name_alt mapcolor7 mapcolor8 mapcolor9 mapcolor13  pop_est gdp_md_est pop_year lastcensus gdp_year                    economy
0     <NA>         5         6         8          7 28400000    22270.0       NA       1979       NA  7. Least developed region
1     <NA>         3         2         6          1 12799293   110300.0       NA       1970       NA  7. Least developed region
2     <NA>         1         4         1          6  3639453    21810.0       NA       2001       NA       6. Developing region
3     <NA>         2         1         3          3  4798491   184300.0       NA       2010       NA       6. Developing region
4     <NA>         3         1         3         13 40913584   573900.0       NA       2010       NA    5. Emerging region: G20
5     <NA>         3         1         2         10  2967004    18770.0       NA       2001       NA       6. Developing region
6     <NA>         4         5         1         NA     3802      760.4       NA         NA       NA       6. Developing region
7     <NA>         7         5         9         11      140       16.0       NA         NA       NA       6. Developing region
8     <NA>         1         2         2          7 21262641   800200.0       NA       2006       NA 2. Developed region: nonG7
9     <NA>         3         1         3          4  8210281   329500.0       NA       2011       NA 2. Developed region: nonG7
               income_grp wikipedia fips_10 iso_a2 iso_a3 iso_n3 un_a3 wb_a2 wb_a3 woe_id adm0_a3_is adm0_a3_us adm0_a3_un adm0_a3_wb
0           5. Low income        NA    <NA>     AF    AFG    004   004    AF   AFG     NA        AFG        AFG         NA         NA
1  3. Upper middle income        NA    <NA>     AO    AGO    024   024    AO   AGO     NA        AGO        AGO         NA         NA
2  4. Lower middle income        NA    <NA>     AL    ALB    008   008    AL   ALB     NA        ALB        ALB         NA         NA
3 2. High income: nonOECD        NA    <NA>     AE    ARE    784   784    AE   ARE     NA        ARE        ARE         NA         NA
4  3. Upper middle income        NA    <NA>     AR    ARG    032   032    AR   ARG     NA        ARG        ARG         NA         NA
5  4. Lower middle income        NA    <NA>     AM    ARM    051   051    AM   ARM     NA        ARM        ARM         NA         NA
6 2. High income: nonOECD        NA    <NA>     AQ    ATA    010  <NA>  <NA>  <NA>     NA        ATA        ATA         NA         NA
7 2. High income: nonOECD        NA    <NA>     TF    ATF    260  <NA>  <NA>  <NA>     NA        ATF        ATF         NA         NA
8    1. High income: OECD        NA    <NA>     AU    AUS    036   036    AU   AUS     NA        AUS        AUS         NA         NA
9    1. High income: OECD        NA    <NA>     AT    AUT    040   040    AT   AUT     NA        AUT        AUT         NA         NA
                continent               region_un                 subregion                  region_wb name_len long_len abbrev_len tiny
0                    Asia                    Asia             Southern Asia                 South Asia       11       11          4   NA
1                  Africa                  Africa             Middle Africa         Sub-Saharan Africa        6        6          4   NA
2                  Europe                  Europe           Southern Europe      Europe & Central Asia        7        7          4   NA
3                    Asia                    Asia              Western Asia Middle East & North Africa       20       20          6   NA
4           South America                Americas             South America  Latin America & Caribbean        9        9          4   NA
5                    Asia                    Asia              Western Asia      Europe & Central Asia        7        7          4   NA
6              Antarctica              Antarctica                Antarctica                 Antarctica       10       10          4   NA
7 Seven seas (open ocean) Seven seas (open ocean)   Seven seas (open ocean)         Sub-Saharan Africa       22       35         10    2
8                 Oceania                 Oceania Australia and New Zealand        East Asia & Pacific        9        9          4   NA
9                  Europe                  Europe            Western Europe      Europe & Central Asia        7        7          5   NA
  homepart                       geometry
0        1 MULTIPOLYGON (((61.21082 35...
1        1 MULTIPOLYGON (((16.32653 -5...
2        1 MULTIPOLYGON (((20.59025 41...
3        1 MULTIPOLYGON (((51.57952 24...
4        1 MULTIPOLYGON (((-65.5 -55.2...
5        1 MULTIPOLYGON (((43.58275 41...
6        1 MULTIPOLYGON (((-59.57209 -...
7       NA MULTIPOLYGON (((68.935 -48....
8        1 MULTIPOLYGON (((145.398 -40...
9        1 MULTIPOLYGON (((16.97967 48...
view(countries)

ggplot(countries) +
  geom_sf(aes(fill = income_grp))


countries %>% 
  filter(continent == "Africa") %>%
  ggplot() +
    geom_sf(aes(fill = income_grp))

Sealt saab ka täpsemat administratiivse alamjaotuse infot käsuga ne_states, millele peab andma argumendiks ette riigi. Eesti kohta on see andmestik natuke väikese resolutsiooniga, kuid suuremate riikide jaoks on väga hea.

ne_states(country = "Estonia", returnclass = "sf")
Simple feature collection with 15 features and 83 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 21.83237 ymin: 57.51582 xmax: 28.18648 ymax: 59.67088
CRS:           +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
First 10 features:
             featurecla scalerank adm1_code diss_me iso_3166_2 wikipedia iso_a2 adm0_sr     name                              name_alt
134  Admin-1 scale rank         8  EST-2350    2350      EE-84      <NA>     EE       1 Viljandi Viljandimaa|Viljandi maakond|Vilyandi
137  Admin-1 scale rank         8  EST-2346    2346      EE-67      <NA>     EE       5    Pärnu         Paernu|Pärnumaa|Pärnu maakond
139  Admin-1 scale rank         8  EST-2349    2349      EE-82      <NA>     EE       1    Valga                Valgamaa|Valga maakond
142  Admin-1 scale rank         8  EST-2351    2351      EE-86      <NA>     EE       1     Võru             Voru|Võrumaa|Võru maakond
1657 Admin-1 scale rank         8  EST-1655    1655      EE-44      <NA>     EE       1 Ida-Viru          Ida-Virumaa|Ida-Viru maakond
1658 Admin-1 scale rank         8  EST-2347    2347      EE-65      <NA>     EE       1    Põlva          Polva|Põlvamaa|Põlva maakond
1659 Admin-1 scale rank         8  EST-1659    1659      EE-78      <NA>     EE       1    Tartu         Tartumaa|Tartu maakond|Dorpat
1660 Admin-1 scale rank         8  EST-1657    1657      EE-49      <NA>     EE       1   Jõgeva       Jogeva|Jõgevamaa|Jõgeva maakond
2381 Admin-1 scale rank         8  EST-1661    1661      EE-57      <NA>     EE       5    Lääne        Laeaene|Läänemaa|Lääne maakond
2382 Admin-1 scale rank         8  EST-1654    1654      EE-37      <NA>     EE       5    Harju                Harjumaa|Harju maakond
     name_local    type type_en code_local code_hasc note hasc_maybe region region_cod provnum_ne gadm_level check_me datarank abbrev postal
134        <NA> Maakond  County       <NA>     EE.VD <NA>       <NA>   <NA>       <NA>         17          1       20        8   <NA>     VD
137        <NA> Maakond  County       <NA>     EE.PR <NA>       <NA>   <NA>       <NA>          3          1       20        8   <NA>     PR
139        <NA> Maakond  County       <NA>     EE.VG <NA>       <NA>   <NA>       <NA>          8          1       20        8   <NA>     VG
142        <NA> Maakond  County       <NA>     EE.VR <NA>       <NA>   <NA>       <NA>          9          1       20        8   <NA>     VR
1657       <NA> Maakond  County       <NA>     EE.IV <NA>       <NA>   <NA>       <NA>         11          1       20        8   <NA>     IV
1658       <NA> Maakond  County       <NA>     EE.PL <NA>       <NA>   <NA>       <NA>         10          1       20        8   <NA>     PL
1659       <NA> Maakond  County       <NA>     EE.TA <NA>      EE.JN   <NA>       <NA>         12          1       20        8   <NA>     TA
1660       <NA> Maakond  County       <NA>     EE.JN <NA>       <NA>   <NA>       <NA>         13          1       20        8   <NA>     JN
2381       <NA> Maakond  County       <NA>     EE.LN <NA>       <NA>   <NA>       <NA>          2          1       20        8   <NA>     LN
2382       <NA> Maakond  County       <NA>     EE.HA <NA>       <NA>   <NA>       <NA>          4          1       20        8   <NA>     HA
     area_sqkm sameascity labelrank name_len mapcolor9 mapcolor13 fips fips_alt  woe_id                    woe_label woe_name latitude
134          0          7         7        8         1         10 EN20     <NA> 2345289 Viljandi County, EE, Estonia Viljandi  58.3005
137          0         NA         8        5         1         10 EN11     <NA> 2345283    Parnu County, EE, Estonia    Pärnu  58.1294
139          0         NA         8        5         1         10 EN19     <NA> 2345288    Valga County, EE, Estonia    Valga  57.9402
142          0         NA         8        4         1         10 EN21     <NA> 2345290     Voru County, EE, Estonia     Võru  57.7735
1657         0         NA         8        8         1         10 EN03     <NA> 2345278 Ida-Viru County, EE, Estonia Ida-Viru  59.1333
1658         0         NA         8        5         1         10 EN12     <NA> 2345284    Polva County, EE, Estonia    Põlva  58.0905
1659         0         NA         8        5         1         10 EN18     EN05 2345287    Tartu County, EE, Estonia    Tartu  58.3727
1660         0         NA         8        6         1         10 EN05     <NA> 2345280   Jogeva County, EE, Estonia   Jõgeva  58.7313
2381         0         NA         8        5         1         10 EN07     <NA> 2345281    Laane County, EE, Estonia    Lääne  59.0075
2382         0         NA         8        5         1         10 EN01     <NA> 2345276    Harju County, EE, Estonia    Harju  59.3206
     longitude sov_a3 adm0_a3 adm0_label   admin geonunit gu_a3  gn_id     gn_name   gns_id    gns_name gn_level gn_region gn_a1_code
134    25.5603    EST     EST          2 Estonia  Estonia   EST 587590 Viljandimaa -2626501 Viljandimaa        1      <NA>      EE.20
137    23.9802    EST     EST          2 Estonia  Estonia   EST 589576    Parnumaa -2624434    Parnumaa        1      <NA>      EE.11
139    26.0733    EST     EST          2 Estonia  Estonia   EST 587875    Valgamaa -2626210    Valgamaa        1      <NA>      EE.19
142    26.9602    EST     EST          2 Estonia  Estonia   EST 587448     Vorumaa -2626647     Vorumaa        1      <NA>      EE.21
1657   27.4446    EST     EST          2 Estonia  Estonia   EST 592075 Ida-Virumaa -2621851 Ida-Virumaa        1      <NA>      EE.03
1658   27.1696    EST     EST          2 Estonia  Estonia   EST 589373       Polva -2624654    Polvamaa        1      <NA>      EE.12
1659   26.7967    EST     EST          2 Estonia  Estonia   EST 588334    Tartumaa -2625738    Tartumaa        1      <NA>      EE.18
1660   26.5975    EST     EST          2 Estonia  Estonia   EST 591901   Jogevamaa -2622030   Jogevamaa        1      <NA>      EE.05
2381   23.2541    EST     EST          2 Estonia  Estonia   EST 590856  Laeaenemaa -2623107    Laanemaa        1      <NA>      EE.07
2382   25.1734    EST     EST          2 Estonia  Estonia   EST 592170    Harjumaa -2621754    Harjumaa        1      <NA>      EE.01
     region_sub sub_code gns_level gns_lang gns_adm1 gns_region min_label max_label min_zoom wikidataid name_ar name_bn        name_de
134        <NA>     <NA>         1      zho     EN20       <NA>         7        11        7    Q192061    <NA>    <NA> Kreis Viljandi
137        <NA>     <NA>         1      zho     EN11       <NA>         7        11        7    Q185036    <NA>    <NA>    Kreis Pärnu
139        <NA>     <NA>         1      zho     EN19       <NA>         7        11        7    Q192362    <NA>    <NA>    Kreis Valga
142        <NA>     <NA>         1      zho     EN21       <NA>         7        11        7    Q188076    <NA>    <NA>     Kreis Võru
1657       <NA>     <NA>         1      zho     EN03       <NA>         7        11        7    Q189963    <NA>    <NA> Kreis Ida-Viru
1658       <NA>     <NA>         1      zho     EN12       <NA>         7        11        7    Q191813    <NA>    <NA>    Kreis Põlva
1659       <NA>     <NA>         1      zho     EN18       <NA>         7        11        7    Q192370    <NA>    <NA>    Kreis Tartu
1660       <NA>     <NA>         1      zho     EN05       <NA>         7        11        7    Q189974    <NA>    <NA>   Kreis Jõgeva
2381       <NA>     <NA>         1      zho     EN07       <NA>         7        11        7    Q189968    <NA>    <NA>    Kreis Lääne
2382       <NA>     <NA>         1      zho     EN01       <NA>         7        11        7    Q180200    <NA>    <NA>    Kreis Harju
             name_en             name_es           name_fr name_el name_hi     name_hu         name_id     name_it name_ja name_ko     name_nl
134  Viljandi County Condado de Viljandi Comté de Viljandi    <NA>    <NA> Viljandimaa County Viljandi Viljandimaa    <NA>    <NA> Viljandimaa
137     Pärnu County    Condado de Pärnu    comté de Pärnu    <NA>    <NA>    Pärnumaa    County Pärnu    Pärnumaa    <NA>    <NA>    Pärnumaa
139     Valga County    Condado de Valga    Comté de Valga    <NA>    <NA>    Valgamaa    County Valga    Valgamaa    <NA>    <NA>    Valgamaa
142      Võru County     Condado de Võru     Comté de Võru    <NA>    <NA>     Võrumaa     County Võru     Võrumaa    <NA>    <NA>     Võrumaa
1657 Ida-Viru County Condado de Ida-Viru Comté de Viru-Est    <NA>    <NA> Ida-Virumaa County Ida-Viru Ida-Virumaa    <NA>    <NA> Ida-Virumaa
1658    Põlva County    Condado de Põlva    Comté de Põlva    <NA>    <NA>    Põlvamaa    County Põlva    Põlvamaa    <NA>    <NA>    Põlvamaa
1659    Tartu County    Condado de Tartu    Comté de Tartu    <NA>    <NA>        <NA>    County Tartu    Tartumaa    <NA>    <NA>    Tartumaa
1660   Jõgeva County   Condado de Jõgeva   Comté de Jõgeva    <NA>    <NA>   Jõgevamaa   County Jõgeva   Jõgevamaa    <NA>    <NA>   Jõgevamaa
2381    Lääne County    Condado de Lääne    comté de Lääne    <NA>    <NA>    Läänemaa    County Lääne    Läänemaa    <NA>    <NA>    Läänemaa
2382    Harju County    Condado de Harju    comté de Harju    <NA>    <NA>    Harjumaa    County Harju    Harjumaa    <NA>    <NA>    Harjumaa
         name_pl     name_pt name_ru      name_sv      name_tr name_vi name_zh      ne_id                       geometry
134  Viljandimaa Viljandimaa    <NA> Viljandi län Viljandi ili    <NA>    <NA> 1159313095 MULTIPOLYGON (((25.33368 58...
137     Pärnumaa    Pärnumaa    <NA>    Pärnu län    Pärnu ili   Pärnu    <NA> 1159313007 MULTIPOLYGON (((25.03486 58...
139     Valgamaa    Valgamaa    <NA>    Valga län    Valga ili    <NA>    <NA> 1159313093 MULTIPOLYGON (((25.62508 57...
142      Võrumaa     Võrumaa    <NA>     Võru län     Võru ili    <NA>    <NA> 1159313097 MULTIPOLYGON (((26.49955 57...
1657 Ida-Virumaa Ida-Virumaa    <NA>  Ida-Virumaa Ida-Viru ili    <NA>    <NA> 1159313077 MULTIPOLYGON (((28.01905 59...
1658    Põlvamaa    Põlvamaa    <NA>    Põlva län    Põlva ili    <NA>    <NA> 1159313089 MULTIPOLYGON (((27.51959 58...
1659    Tartumaa    Tartumaa    <NA>     Tartumaa    Tartu ili    <NA>    <NA> 1159313087 MULTIPOLYGON (((27.42885 58...
1660   Jõgevamaa   Jõgevamaa    <NA>    Jõgevamaa   Jõgeva ili    <NA>    <NA> 1159313081 MULTIPOLYGON (((27.44627 58...
2381    Läänemaa    Läänemaa    <NA>     Läänemaa    Lääne ili    <NA>    <NA> 1159313071 MULTIPOLYGON (((23.5858 58....
2382    Harjumaa    Harjumaa    <NA>     Harjumaa    Harju ili   Harju    <NA> 1159313075 MULTIPOLYGON (((23.71849 59...
ne_states(country = "Estonia", returnclass = "sf") %>% 
  ggplot() +
    geom_sf()


ne_states(country = "United Kingdom", returnclass = "sf") %>% 
  ggplot() +
    geom_sf()

Open Street Maps

Open Street Maps (OSM) on avatud vaste Google Mapsile ning sisaldab kõikvõimalikku kaardimaterjali. Inimesed üle maailma täiendavad seda pidevalt, nii et tegu on pidevas arengus oleva andmebaasiga. Infot on seal kaugelt rohkem kui on mõistlik korraga oma arvutisse laadida, seetõttu tuleb OSM andmete kasutamiseks teha päringuid OSM API-le mis saadab täpselt vajalikud andmed. OSM API väljakutsumine ja sealt saabuvate andmete õigesse formaati teisendamine on implementeeritud paketis osmdata. Sellega töötamise süsteem on järgmine. Vaata OSM wikit, et näha, mida erinevad deifnitsioonid ja nimed andmestikus tähendavad jne

  • Esiteks tuleb defineerida ümbritsev kast (i.k bounding box) neile andmetele, mida tahame alla laadida. Seda saab teha paketi osmdata käsuga getbb, mille argumendiks tuleb panna meid huvitav kohanimi mingis formaadis. Näiteks “Tartu”, “Raplamaa”, “Haabersti”.
getbb("Narva")
       min      max
x 28.01141 28.20904
y 59.29520 59.44386
  • Teiseks tuleb käsus add_osm_feature defineerida mis infot soovitakse saada. Kõikidest tabelitest saab ülevaate funktsiooniga available_features ja konkreetse tabeli alamajotustest available_tags
available_features() %>% tail()
[1] "water"       "wheelchair"  "wholesale"   "width"       "winter_road" "wood"       
available_tags("water")
 [1] "basin"           "canal"           "ditch"           "fish_pass"       "lagoon"          "lake"            "lock"           
 [8] "moat"            "oxbow"           "pond"            "reflecting_pool" "reservoir"       "river"           "stream_pool"    
[15] "wastewater"     
  • Mõned kasulikumad tabelid on

      -   "highway" - kõik teed ja sillad
    
      -   "boundary" - piirid (tag "administrative" annab ametlikud piirid
    
      -   "building" - kõik hooned
    
      -   "water" - kõik siseveekogud: jõed, järved, tiigid
  • Kolmandaks tuleb kõik info alla laadida. Selleks on käsud osmdata_sf() %>% unname_osmdata_sf(). See protsess võib aega võtta ja ei pruugi iga kord õnnestuda. Siis proovida uuesti.

  • Lõpuks saame andmestiku, mis on list erinevatest sf formaadis tabelitest vastavalt objeltitüübile. Selle listi elemendid on

    • osm_points

    • osm_lines

    • osm_polygons

    • osm_multipoints

    • osm_multilines

    • osm_multipolygons

Teeme läbi ühe näite

teed = opq(getbb("Tartu kesklinn")) %>% 
  add_osm_feature(key = "highway") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

#Vaatame, mis informatsiooni on joontena kujutatud kaartidel
teed$osm_lines
Simple feature collection with 1756 features and 88 fields
Geometry type: LINESTRING
Dimension:     XY
Bounding box:  xmin: 26.69676 ymin: 58.36001 xmax: 26.74681 ymax: 58.39059
Geodetic CRS:  WGS 84
First 10 features:
           osm_id      name access addr.city addr.country addr.full addr.housenumber addr.street alt_name amenity area bicycle bridge
27096547 27096547 Taara pst   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
28906993 28906993 Narva mnt   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29394188 29394188      Riia   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29394203 29394203 Narva mnt   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29394205 29394205 Narva mnt   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29394283 29394283      <NA>   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29394711 29394711 Narva mnt   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>    yes
29394713 29394713      <NA>   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29420431 29420431      <NA>   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>    <NA>   <NA>
29420432 29420432      <NA>   <NA>      <NA>         <NA>      <NA>             <NA>        <NA>     <NA>    <NA> <NA>     yes    yes
         bridge.structure building building.levels colour covered created_by        crossing crossing.island cycleway cycleway.both
27096547             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
28906993             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394188             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394203             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394205             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394283             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394711             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29394713             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
29420431             <NA>     <NA>            <NA>   <NA>    <NA>       <NA> traffic_signals              no     <NA>          <NA>
29420432             <NA>     <NA>            <NA>   <NA>    <NA>       <NA>            <NA>            <NA>     <NA>          <NA>
         cycleway.left cycleway.right destination.lanes destination.ref.lanes destination.ref.to.lanes destination.to foot  footway
27096547          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
28906993          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394188          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394203          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394205          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394283          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394711          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29394713          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
29420431          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA> crossing
29420432          <NA>           <NA>              <NA>                  <NA>                     <NA>           <NA> <NA>     <NA>
              full_name handrail  hgv        highway horse incline int_ref junction lane_markings lanes lanes.backward lanes.forward layer
27096547 Taara puiestee     <NA> <NA>    residential  <NA>    <NA>    <NA>     <NA>          <NA>  <NA>           <NA>          <NA>  <NA>
28906993           <NA>     <NA> <NA>          trunk  <NA>    <NA>   E 264     <NA>          <NA>     2           <NA>          <NA>  <NA>
29394188           <NA>     <NA> <NA>          trunk  <NA>    <NA>   E 264     <NA>          <NA>  <NA>           <NA>          <NA>  <NA>
29394203           <NA>     <NA> <NA>          trunk  <NA>    <NA>   E 264     <NA>          <NA>     1           <NA>          <NA>  <NA>
29394205           <NA>     <NA> <NA>          trunk  <NA>    <NA>   E 264     <NA>          <NA>     2           <NA>          <NA>  <NA>
29394283           <NA>     <NA> <NA> secondary_link  <NA>    <NA>    <NA>     <NA>          <NA>  <NA>           <NA>          <NA>  <NA>
29394711           <NA>     <NA> <NA>          trunk  <NA>    <NA>   E 264     <NA>          <NA>     4           <NA>          <NA>     1
29394713           <NA>     <NA> <NA>  tertiary_link  <NA>    <NA>    <NA>     <NA>          <NA>  <NA>           <NA>          <NA>  <NA>
29420431           <NA>     <NA> <NA>        footway  <NA>    <NA>    <NA>     <NA>          <NA>  <NA>           <NA>          <NA>  <NA>
29420432           <NA>     <NA> <NA>     pedestrian  <NA>    <NA>    <NA>     <NA>          <NA>  <NA>           <NA>          <NA>     1
         length length_unit lines  lit maxheight maxspeed maxspeed.type maxweight maxwidth motor_vehicle name.en name.zh noname old_name.de
27096547   <NA>        <NA>  <NA> <NA>      <NA>       30          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
28906993   <NA>        <NA>  <NA> <NA>      <NA>       40          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394188   <NA>        <NA>  <NA> <NA>      <NA>       50          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394203   <NA>        <NA>  <NA> <NA>      <NA>       50          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394205   <NA>        <NA>  <NA> <NA>      <NA>       50          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394283   <NA>        <NA>  <NA> <NA>      <NA>     <NA>          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394711   <NA>        <NA>  <NA> <NA>      <NA>       50          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29394713   <NA>        <NA>  <NA> <NA>      <NA>     <NA>          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29420431   <NA>        <NA>  <NA>  yes      <NA>     <NA>          <NA>      <NA>     <NA>          <NA>    <NA>    <NA>   <NA>        <NA>
29420432   <NA>        <NA>  <NA>  yes      <NA>     <NA>          <NA>      <NA>     <NA>            no    <NA>    <NA>    yes        <NA>
         oneway oneway.bicycle parking.lane.left parking.lane.right postal_code ramp ramp.bicycle  ref roof.colour roof.shape
27096547    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA> <NA>        <NA>       <NA>
28906993    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA>    3        <NA>       <NA>
29394188    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA>    3        <NA>       <NA>
29394203    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA>    3        <NA>       <NA>
29394205    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA>    3        <NA>       <NA>
29394283    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA> <NA>        <NA>       <NA>
29394711   <NA>           <NA>              <NA>               <NA>        <NA> <NA>         <NA>    3        <NA>       <NA>
29394713    yes           <NA>              <NA>               <NA>        <NA> <NA>         <NA> <NA>        <NA>       <NA>
29420431   <NA>           <NA>              <NA>               <NA>        <NA> <NA>         <NA> <NA>        <NA>       <NA>
29420432   <NA>           <NA>              <NA>               <NA>        <NA> <NA>         <NA> <NA>        <NA>       <NA>
         seamark.bridge.category segregated service sidewalk sidewalk.both.bicycle sidewalk.both.surface                source source.hgv
27096547                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
28906993                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394188                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394203                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394205                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394283                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394711                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29394713                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA> Tartu City Government       <NA>
29420431                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
29420432                    <NA>       <NA>    <NA>     <NA>                  <NA>                  <NA>                  <NA>       <NA>
         source.maxspeed start_date step_count  surface tactile_paving tracktype tunnel turn.lanes turn.lanes.forward wheelchair wikidata
27096547            <NA>       <NA>       <NA>     <NA>           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
28906993            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394188            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394203            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394205            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394283            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394711            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29394713            <NA>       <NA>       <NA>  asphalt           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29420431            <NA>       <NA>       <NA>     sett           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
29420432            <NA>       <NA>       <NA> concrete           <NA>      <NA>   <NA>       <NA>               <NA>       <NA>     <NA>
         wikipedia                       geometry
27096547      <NA> LINESTRING (26.70905 58.379...
28906993      <NA> LINESTRING (26.73056 58.379...
29394188      <NA> LINESTRING (26.72028 58.373...
29394203      <NA> LINESTRING (26.7261 58.3863...
29394205      <NA> LINESTRING (26.72647 58.385...
29394283      <NA> LINESTRING (26.73931 58.369...
29394711      <NA> LINESTRING (26.73036 58.379...
29394713      <NA> LINESTRING (26.73056 58.379...
29420431      <NA> LINESTRING (26.725 58.38056...
29420432      <NA> LINESTRING (26.72539 58.380...

Saadavates andmetes on palju müra kuna on arvestatud igasuguste võimalike annotatsioonidega (seega on tabel lai) ja on kokku pandud palju erinva klassiga teesid. Seetõttu tasub andmeid enne joonistamist filtreerida. Hea ülevaate erinevatest tee tüüpidest saab https://wiki.openstreetmap.org/wiki/Key:highway.

teed$osm_lines %>% 
  filter(!(highway %in% c("pedestrian", "path", "cycleway", "service", "footway"))) %>% 
  ggplot() +
   geom_sf()

Sarnaselt saab alla laadida administratiivsed üksused. Need aga tulevad mitmes tasandis (riik, osariik, maakond, vald, küla, …) . Mis on antud tunnusega admin_level. Eesti puhul on admin_level jaotunud umbes järgmiselt.

  • 2 - riik

  • 6 - maakond

  • 7 - vald

  • 8 - linn

  • 9 - külad, linnaosad

  • 10 - asumid

piirid = opq(getbb("Tallinn")) %>% 
  add_osm_feature(key = "boundary", value = "administrative") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

piirid$osm_multipolygons %>% 
  filter(admin_level == 8) %>% 
  ggplot() +
    geom_sf()


piirid$osm_multipolygons %>% 
  filter(admin_level == 9) %>% 
  ggplot() +
    geom_sf()


piirid$osm_multipolygons %>% 
  filter(admin_level == 10) %>% 
  ggplot() +
    geom_sf()

Tõmbame all ka veekogud ja joonistame need kaardile. Kuna veekogud tulevad nii joonte, polügonide kui multipolügonidena, peame neid joonistama ka mitmes kihis.


vesi = opq(getbb("Tartu kesklinn")) %>% 
  add_osm_feature(key = "water") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

ggplot() +
  geom_sf(color = "lightblue", data = vesi$osm_lines) +
  geom_sf(fill = "lightblue", data = vesi$osm_polygons) +
  geom_sf(fill = "lightblue", data = vesi$osm_multipolygons)

Nagu näha on tihti probleemiks, et objektid ulatuvad kaugele algest ümbritsevast kastist välja seetõttu võib seda ümbritseva kasti koordinaadid anda ette ka funktsioonidele xlim ja ylim.

bb = getbb("Tartu kesklinn")
ggplot() +
  geom_sf(color = "lightblue", data = vesi$osm_lines) +
  geom_sf(fill = "lightblue", data = vesi$osm_polygons) +
  geom_sf(fill = "lightblue", data = vesi$osm_multipolygons) +
  geom_sf(data = teed$osm_lines) +
  xlim(bb[1, ]) + #tsentreerib kaardi nendesse piiridesse, mis bb[] annab
  ylim(bb[2, ]) 

Ülesanne

  • Joonista Rakvere kaart, kus on peal hooned, teed (teist värvi kui hooned) ja linna piir (paksemana, kui muud jooned). Kõik andmed tõmba OSM-st. Kui saad kiirelt valmis proovi erinevaid võimalusi kaarti ilusamaks teha.
#linnapiirid
bb = getbb("Rakvere")

#Hooned
v_hoone = opq(bb) %>% 
  add_osm_feature(key = "building") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

#Teed
v_teed = opq(bb) %>% 
  add_osm_feature(key = "highway") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

#Administratiivüksused
v_admin = opq(bb) %>% 
  add_osm_feature(key = "boundary", value = "administrative") %>% 
  osmdata_sf() %>% 
  unname_osmdata_sf()

ggplot() + 
  geom_sf(fill="white", color = NA, data = v_hoone$osm_polygons)+
  geom_sf(color = "grey80", data = v_teed$osm_lines)+
  geom_sf(color = "white", size = 2, fill = NA, data = v_admin$osm_multipolygons %>% filter(admin_level == 7) %>% filter(name == "Rakvere linn"))+
  xlim(bb[1,])+
  ylim(bb[2,])+
  theme_void()+
  theme(plot.background = element_rect(fill = "black"))

LS0tCnRpdGxlOiAiUHJha3Rpa3VtIDcgLSBLYWFyZGlkIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIyBTaXNzZWp1aGF0dXMKClTDpG5hZXMgcHJha3Rpa3VtIG9uIGVzaW1lbmUga2FoZXN0LCBrdXMgdmFhdGFtZSBrYWFyZGlhbmRtZWlkLiBNZSBrYXN1dGFtZSBrYWFyZGlhbmRtZXRlIGphb2tzIHNpbXBsZSBmZWF0dXJlcyBmb3JtYWF0aSBtaWRhIGBSYC1zIGltcGxlbWVudGVlcmliIHBha2V0dCBuaW1lZ2EgYHNmYC4gTG9lbWUgc2lzc2Uga2EgcGFrZXRpIG9zbWRhdGEsIG1pbGxlZ2EgdmFhdGFtZSBww6RyYXN0cG9vbGUga3VpZGFzIHTDtW1tYXRhIE9wZW4gU3RyZWV0IE1hcHMga2FhcmRpaW5mb3QuCgpgYGB7cn0KbGlicmFyeShzZikKbGlicmFyeShvc21kYXRhKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ3NwYXRpYWwpCmxpYnJhcnkocm5hdHVyYWxlYXJ0aCkKbGlicmFyeShyZ2VvcykKYGBgCgojIyBLYWFyZGlhbmRtZWQgamEgbmVuZGUgbsOkaXRhbWluZQoKTsOkaWRpc2FuZG1lc3Rpa3VuYSBrYXN1dGFtZSBFZXN0aSBtYWFrb25kYWRlIGphIHZhbGRhZGUgYW5kbWVzdGlra3UuCgpgYGB7cn0KbG9hZCgiZWVzdGkuUkRhdGEiLCB2ZXJib3NlID0gVCkKYGBgCgpOZWVkIGFuZG1lZCBvbiBmb3JtYWFkaXMgYHNmYCwgbWlzIG9uIHNpc3VsaXNlbHQgYW5kbWV0YWJlbCwga3VzIG9uIMO8a3MgdmVlcmcgKHRhdmFsaXNlbHQgbmltZGVnYSBgZ2VvbWV0cnlgKSBtaWxsZXMgaG9pdGFrc2UgdmVrdG9ya3VqdWwgb2JqZWt0aSBlc2l0dXN0LiBMaXNha3Mgb24gc2VsbGVsZSB0YWJlbGlsIGVyYWxkaSBww6RpcyBtaXMgaG9pYWIgaW5mb3JtYXRzaW9vbmkgYW5kbWV0ZSB0w7zDvGJpLCBhc3Vrb2hhIGphIHByb2pla3RzaW9vbmkga29odGEuCgpgYGB7cn0KbWFha29uZApgYGAKClR1bm51cyBgZ2VvbWV0cnlgIHbDtWliIG9sbGEga3VqdWwgUE9JTlQsIExJTkUsIFBPTFlHT04sIE1VTFRJUE9JTlQsIE1VTFRJTElORSBqYSBNVUxUSVBPTFlHT04uIElnYSBzZiBvYmpla3Qgc2lzYWxkYWIgdmFpZCDDvGh0ZSB0w7zDvHBpIGdlb21ldHJ5IGVsZW1lbnRlLiBNVUxUSVBPTFlHT04gdMOkaGVuZGFiLCBldCB0ZWdlbWlzdCBvbiBrYWhldsOkw6RydHVzZWxpc2UgdHVsYmFnYSwgbWlsbGUgdsOkw6RydHVzZWQgbcOkw6RyYXZhZCBodWxrbnVyZ2Ega8O8bGplZC4KClNpc3VsaXNlbHQgc2FhYiBzZWxsZWxlIGFuZG1ldGFiZWxpbCB0ZWhhIGvDtWlraSBvcGVyYXRzaW9vbmUsIG1pZGEgbWUgc2FhbWUgdGVoYSB0YXZhbGlzZSBhbmRtZXRhYmVsaWdhLgoKYGBge3J9CnZhbGQgJT4lIAogIG11dGF0ZShMaW5uID0gc3RyX2RldGVjdChPTklNSSwgImxpbm4iKSkKCnZhbGQgJT4lIAogIGZpbHRlcihNTklNSSA9PSAiU2FhcmUgbWFha29uZCIpCmBgYAoKQW5kbWVpZCBgc2ZgIGZvcm1hYWRpcyBzYWFiIHZpc3VhbGlzZWVyaWRhIGBnZ3Bsb3QyYC1nYS4gU2VsbGVrcyBvbiBvbGVtYXMgZXJhbGRpIGZ1bmt0c2lvb24gYGdlb21fc2ZgLgoKYGBge3J9CmdncGxvdChtYWFrb25kKSArCiAgZ2VvbV9zZigpCgpnZ3Bsb3QobWFha29uZCkgKwogIGdlb21fc2YoY29sb3IgPSAib3JhbmdlIiwgZmlsbCA9ICJsaWdodGJsdWUiKQpgYGAKCkVyaW5ldmF0ZWwga2lodGlkZWwgc2FhYiBuw6RpZGF0YSBlcmluZXZhaWQgYW5kbWVzdGlra2UuCgpgYGB7cn0KZ2dwbG90KG1hYWtvbmQpICsKICBnZW9tX3NmKGZpbGwgPSAibGlnaHRibHVlIikgKwogIGdlb21fc2YoY29sb3IgPSAib3JhbmdlIiwgZGF0YSA9IHZhbGQgJT4lIGZpbHRlcihNTklNSSA9PSAiSGFyanUgbWFha29uZCIpKSAKYGBgCgpFdCBnZW9ncmFhZmlsaXNpIGFuZG1laWQgc2Fha3MgcGFybWVpbmkgc2lsZGlzdGFkYSBvbiBsb29kdWQgZnVua3RzaW9vbmlkIGBnZW9tX3NmX2xhYmVsYCBqYSBgZ2VvbV9zZl90ZXh0YC4gU2FhbWUga2FzdXRhZGEgYWludWx0IGdlb21fc2ZfLi4uLiwgc2VzdCBtZWlsIHBvbGUgeCBqYSB5IGtvb3JkaW5hYXRlIGphIG1hc2luIMO8cml0YWIgc2lsZGkgcGFubmEgbGlodHNhbHQgb2JqZWt0aSAobWFha29uZCkga2Vza2VsZSAKCmBgYHtyfQpnZ3Bsb3QobWFha29uZCkgKwogIGdlb21fc2YoZmlsbCA9ICJsaWdodGJsdWUiKSArCiAgZ2VvbV9zZl9sYWJlbChhZXMobGFiZWwgPSBNTklNSSkpCgpnZ3Bsb3QobWFha29uZCkgKwogIGdlb21fc2YoZmlsbCA9ICJsaWdodGJsdWUiKSArCiAgZ2VvbV9zZl90ZXh0KGFlcyhsYWJlbCA9IE1OSU1JKSkKYGBgCgpLYXN1dGFkZXMgc2FtYSBzw7xudGFrc2l0IG5hZ3UgbWUgcmFrZW5kYXNpbWUgdsO1cmd1c3Rpa2UgcHVodWwgc2FhbWUgbWUga2Egc2lpbiBzaWx0aWRlIGFydnUgdsOkaGVuZGFkYSwgdsO1dHRlcyBhbmRtZXN0aWt1c3QgYWxhbWh1bGtpLgoKYGBge3J9CmdncGxvdChtYWFrb25kKSArCiAgZ2VvbV9zZihmaWxsID0gImxpZ2h0Ymx1ZSIpICsKICBnZW9tX3NmX2xhYmVsKGFlcyhsYWJlbCA9IE1OSU1JKSwgZGF0YSA9IH4gLnggJT4lIGZpbHRlcihNTklNSSAlaW4lIGMoIkhpaXUgbWFha29uZCIsICJTYWFyZSBtYWFrb25kIikpKSAKYGBgCgpMb29tdWxpa3VsdCBzYWFiIHBpbGRpbCBtdXV0YSBrYSB0YXVzdGEgamEgdsOkbGphbsOkZ2VtaXN0IGthc3V0YWRlcyBgdGhlbWVfKmAgZnVua3RzaW9vbmUuIE5hZ3UgdsO1cmd1c3Rpa2VnaSBwdWh1bCwgb24gYHRoZW1lX3ZvaWRgIGhlYSB2YWxpaywgZXQgcHVodGFtYWlkIHBpbHRlIHNhYWRhLiBLdWlkIGthIG11dWQgZnVua3RzaW9vbmlkLCBuw6RpdGVrcyB0aGVtZV9idywgdMO2w7Z0YXZhZC4gTWVpbCBwb2xlIGVuYW1hc3RpIHZhamEgdGVhZGEsIG1pcyBuZWVkIGtvb3JkaW5hYWRpZCBvbiB0w6Rwc2VsdC4gU2VsbGVwIG9uIHRoZW1lX3ZvaWQgaGVhIGthLgoKYGBge3J9CmdncGxvdChtYWFrb25kKSArCiAgZ2VvbV9zZihmaWxsID0gImxpZ2h0Ymx1ZSIpICsKICBnZW9tX3NmX2xhYmVsKGFlcyhsYWJlbCA9IE1OSU1JKSwgZGF0YSA9IH4gLnggJT4lIGZpbHRlcihNTklNSSAlaW4lIGMoIkhpaXUgbWFha29uZCIsICJTYWFyZSBtYWFrb25kIikpKSArCiAgdGhlbWVfYncoKQoKZ2dwbG90KG1hYWtvbmQpICsKICBnZW9tX3NmKGZpbGwgPSAibGlnaHRibHVlIikgKwogIGdlb21fc2ZfbGFiZWwoYWVzKGxhYmVsID0gTU5JTUkpLCBkYXRhID0gfiAueCAlPiUgZmlsdGVyKE1OSU1JICVpbiUgYygiSGlpdSBtYWFrb25kIiwgIlNhYXJlIG1hYWtvbmQiKSkpICsKICB0aGVtZV92b2lkKCkKYGBgCgpFdCBrYWFydCBvbGVrcyBlZmVrdHNlbSB2w7VpYiBtdXV0YSBrYSBtdWlkIHBhcmFtZWV0cmVpZC4gTsOkaXRla3Mga2FhcmRpZCB0dW1lZGFsIHRhdXN0YWwgbsOkZXZhZCB0aWh0aSB2w6RsamEgdsOkZ2EgcGlsa3Vww7zDvGR2YWQuCgpgYGB7cn0KZ2dwbG90KG1hYWtvbmQpICsKICBnZW9tX3NmKGZpbGwgPSBOQSwgY29sb3IgPSAid2hpdGUiKSArCiAgdGhlbWVfdm9pZCgpICsKICB0aGVtZShwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJibGFjayIpKQpgYGAKCkthYXJ0aWRlbGUgbGlzYXRha3NlIHRpaHRpIGthIG3DtcO1dGthdmEgamEgbm9vbGVrZSBtaXMgbsOkaXRhYiBrdXMgc3V1bmFzIG9uIHDDtWhpLiBLYSBtZWllIGpvb25pc3RhdHVkIGdyYWFmaWt1dGVsIG9uIHNlZSB2w7VpbWFsaWssIGthc3V0YWRlcyBwYWtldHRpIGBnZ3NwYXRpYWxgLCBuaW5nIHNlYWx0IGZ1bmt0c2lvb25lIGBhbm5vdGF0aW9uX3NjYWxlYCBqYSBgYW5ub3RhdGlvbl9ub3J0aF9hcnJvd2AuIHBhZF95IHTDtXN0YWIgbm9vbGVrZXN0IMO8bGVzcG9vbGUKCmBgYHtyfQpnZ3Bsb3QobWFha29uZCkgKwogIGdlb21fc2YoZmlsbCA9ICJsaWdodGJsdWUiKSArCiAgZ2VvbV9zZl9sYWJlbChhZXMobGFiZWwgPSBNTklNSSksIGRhdGEgPSB+IC54ICU+JSBmaWx0ZXIoTU5JTUkgJWluJSBjKCJIaWl1IG1hYWtvbmQiLCAiU2FhcmUgbWFha29uZCIpKSkgKwogIGFubm90YXRpb25fc2NhbGUobG9jYXRpb24gPSAiYmwiLCB3aWR0aF9oaW50ID0gMC4zKSArCiAgYW5ub3RhdGlvbl9ub3J0aF9hcnJvdyhsb2NhdGlvbiA9ICJibCIsIHBhZF95ID0gdW5pdCgwLjMsICJpbiIpLCBzdHlsZSA9IG5vcnRoX2Fycm93X2ZhbmN5X29yaWVudGVlcmluZygpKSArCiAgdGhlbWVfdm9pZCgpCgpgYGAKCiMjIyMgw5xsZXNhbm5lCgotICAgSm9vbmlzdGEga2FhcnQgSGFyanVtYWEgdmFsZGFkZXN0IChoZWxlZGFtYXQgdsOkcnZpIHRhdXN0YWdhKSBuaW5nIGxpc2Egc2VsbGVsZSBUYWxsaW5uIHR1bWVkYW1hIHRhdXN0YWdhLiBUYWxsaW5uYSBqdXVyZGUgcGFuZSBrYSBzaWx0IGxpbm5hIG5pbWVnYS4gRWVtYWxkYWdlIHBpbGRpZGx0IGthIGvDtWlrIHRlbGplZCBqYSBtdXUgbmluZyBsaXNhZ2Ugw7xsZXMgdmFzYWt1c3NlIG51cmthIHNrYWFsYSBqYSBww7VoamFzdXVuYWxpbmUgbm9vbC4KCmBgYHtyfQp2YWxkICU+JSAKICBmaWx0ZXIoTU5JTUkgPT0gIkhhcmp1IG1hYWtvbmQiKSAlPiUgCiAgZ2dwbG90KCkgKwogIGdlb21fc2YoZmlsbCA9ICJsaWdodGJsdWUiKSArCiAgZ2VvbV9zZihmaWxsID0gImRhcmtibHVlIiwgZGF0YSA9IH4ueCAlPiUgZmlsdGVyKE9OSU1JID09ICJUYWxsaW5uIikpKwogIGdlb21fc2ZfbGFiZWwoYWVzKGxhYmVsID0gT05JTUkpLCBkYXRhID0gfiAueCAlPiUgZmlsdGVyKE9OSU1JID09ICJUYWxsaW5uIikpICsKICBhbm5vdGF0aW9uX3NjYWxlKGxvY2F0aW9uID0gInRsIiwgd2lkdGhfaGludCA9IDAuMykgKwogIGFubm90YXRpb25fbm9ydGhfYXJyb3cobG9jYXRpb24gPSAidGwiLCBwYWRfeSA9IHVuaXQoMC4zLCAiaW4iKSwgc3R5bGUgPSBub3J0aF9hcnJvd19mYW5jeV9vcmllbnRlZXJpbmcoKSkgKwogIHRoZW1lX3ZvaWQoKQpgYGAKCgojIyBWw6Rydml0dWQga2FhcmRpZAoKw5xrcyBsZXZpbnVtYWlkIGthYXJ0aWRlIGthc3V0dXNhbGFzaWQgYW5kbWV0ZWFkdXNlcyBvbiBtaW5naSB0dW5udXNlIGrDpHJnaSB2w6Rydml0dWQga2FhcmRpZCAoKmkuayBjbG9yb3BldGggbWFwcyopLiBFZWxuZXZhIHDDtWhqYWwgcG9sZSB2w6RnYSByYXNrZSBhcnZhdGEga3VpZGFzIG5lbmRlIGpvb25pc3RhbWluZSB2w7VpYiBrw6RpYSwga3VuYSBzYWFtZSBrYXN1dGFkYSBzYXJuYXNlaWQgYGdncGxvdDJgIG5pcHBlIG5hZ3UgZWVsbmV2YXRlc2tpIHByYWt0aWt1bWlkZXMuIEVubmUgYWdhIGt1aSBsw6RoZW1lIGthYXJ0aWRlIGpvb25pc3RhbWlzZSBqdXVyZGUgbG9lbWUgc2lzc2UgYW5kbWVzdGlrdSwgbWlzIGtpcmplbGRhYiBrb3Jvb25hdmFrdHNpbmVlcmltaXNlIGhldGtlc2Vpc3UgdmFudXNlZ3J1cHBpZGVzIGphIHNvbyBrYXVwYSBrdXVww6R2YSAxOC8wMy8yMDIxIHNlaXN1Z2EuCgpgYGB7cn0KbG9hZCgidmFrdHNpaW4uUkRhdGEiLCB2ZXJib3NlID0gVCkKCnZha3RzaWluCmBgYAoKU2VsbGVrcywgZXQgbWVpbCB0ZWtpa3MgbGlodHNhbSBhbmRtZXN0aWsgbWlkYSB1dXJpZGEgc3VtbWVlcmltZSBhcnZ1ZCBtYWFrb25uYSBrYXVwYS4KCmBgYHtyfQp2ID0gdmFrdHNpaW4gJT4lIAogIGdyb3VwX2J5KENvdW50eSkgJT4lIAogIHN1bW1hcml6ZSgKICAgIFRvdGFsQ291bnQgPSBzdW0oVG90YWxDb3VudCksCiAgICBUb3RhbFBvcHVsYXRpb24gPSBzdW0oUG9wdWxhdGlvbikKICApIAoKdgpgYGAKCk7DvMO8ZCBzYWFtZSBzZWxsZSBhbmRtZXN0aWt1IGxpaXRhIG9sZW1hc29sZXZhbGUgbWFha29ubmEgYW5kbWVzdGlrdWxlLiBTZWxsZWtzIG90c3RhcmJla3Mgc2FhYiBrYXN1dGFkYSBgKl9qb2luYCBwZXJla29ubmEga8Okc2t1c2lkLiBOZWVkIG9uIGFuYWxvb2dzZWQgU1FMIGpvaW4ga8Okc2t1ZGVnYSBqYSBzaW5uYSBwZXJla29uZGEga3V1bHV2YWQuCgotICAgYGxlZnRfam9pbmAgLSBqw6R0YWIgYWxsZXMga8O1aWsgcmVhZCB2YXNha3Bvb2xzZXN0IHRhYmVsaXN0CgotICAgYHJpZ2h0X2pvaW5gIC0gasOkdGFiIGFsbGVzIGvDtWlrIHJlYWQgcGFyZW1wb29sc2VzdCB0YWJlbGlzdAoKLSAgIGBmdWxsX2pvaW5gIC0gasOkdGFiIGFsbGVzIGvDtWlrIHJlYWQgbcO1bGVtYXN0IHRhYmVsaXN0CgotICAgYGlubmVyX2pvaW5gIC0gasOkdGFiIGFsbGVzIHJlYWQgbWlzIG9uIG9sZW1hcyBtw7VsZW1hcyB0YWJlbGlzCgrDnGhlbmRhbWluZSBrw6RpYiB2YWlraW1pcyB0dW5udXN0ZSBhbHVzZWwgbWlsbGVsIG9uIHNhbWEgbmltaS4gw5xoZW5kYW1lIG7DvMO8ZCB0YWJlbGlkIGB2YCBqYSBgbWFha29uZGAuICoqUGFuZSB0w6RoZWxlLCBldCB0YXN1YiDDvGhlZGFkYSBhbmRtZWQgc2Ygb2JqZWt0aSBrw7xsZ2UgbWl0dGUgdmFzdHVwaWRpLCBzZXN0IG11aWR1IG11dXR1YiBvYmpla3RpIHTDvMO8cC4qKgoKYGBge3J9CiNNdXVkYW1lIG5pbWUsIGV0IGpvaW5pIHR1bHAgb2xla3Mgc2FtYSBuaW1lZ2EgKE1OSU1JKQp2bSA9IG1hYWtvbmQgJT4lIAogIGxlZnRfam9pbih2ICU+JSByZW5hbWUoTU5JTUkgPSBDb3VudHkpKQoKdm0KCiNLdWkgbmlpIHRlZW1lLCBuYWd1IHNpaW4sIHNpaXMgc2FhYiB0dWxlbXVzZWtzIGRhdGFmcmFtZSBqYSBlaSBzYWEga2FzdXRhZGEga2FhcmRpIHBha2V0dGUKdiAlPiUgCiAgcmVuYW1lKE1OSU1JID0gQ291bnR5KSAlPiUgCiAgbGVmdF9qb2luKG1hYWtvbmQpCmBgYAoKTsO8w7xkIHNhYW1lIGpvb25pc3RhZGEga2FhcmRpIG1pcyBvbiB2w6Rydml0dWQgdmFrdHNpbmVlcmltaXN0ZSBhcnZ1IGrDpHJnaS4KCmBgYHtyfQojVmFrdHNpbmVlcml0dXRlIG9zYWthYWwga29ndSBtYWFza29ubmEgcmFodmFzdGlrdXN0CmdncGxvdCh2bSkgKyAKICBnZW9tX3NmKGFlcyhmaWxsID0gVG90YWxDb3VudC9Ub3RhbFBvcHVsYXRpb24pKQpgYGAKClNlZGEgcGlsdGkgc2FhYiBtb2RpZml0c2VlcmlkYSBrYXN1dGFkZXMgZ2dwbG90Mi1zdCB0dXR0YXZhaWQgdsO1dHRlaWQuCgpgYGB7cn0KI0xpc2FtZSBzaWxkaSwgbXV1ZGFtZSBncmFkaWVudGkgdsOkcnZpIGphIGthb3RhbWUgdGVsamVkIMOkcmEuCmdncGxvdCh2bSkgKyAKICBnZW9tX3NmKGFlcyhmaWxsID0gVG90YWxDb3VudC9Ub3RhbFBvcHVsYXRpb24pKSArCiAgZ2VvbV9zZl90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKFRvdGFsQ291bnQvVG90YWxQb3B1bGF0aW9uLCAzKSksIGNvbG9yID0gIndoaXRlIikgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQoIlByb3BWYWNjaW5hdGVkIiwgbG93ID0gImxpZ2h0Z3JlZW4iLCBoaWdoID0gImRhcmtncmVlbiIpICsKICB0aGVtZV92b2lkKCkKICAKYGBgCgpBbmRtZXRhYmVsaXRlIMO8aGVuZGFtaXNlbCBwZWFiIG9sZW1hIGV0dGV2YWF0bGlrIGpvaW5pZ2EsIGV0IG1laWUgcmVhZCBlaSBwYWxqdW5la3MuIEt1aSBzYW1hIG1hYWtvbm5hIGtvaHRhIG9uIG1pdHUgYW5kbWVwdW5rdGksIHNpaXMgbWFha29uZGFkZSB0YWJlbGkgcmlkdSBwYWxqdW5kYXRha3NlIG5paSBwYWxqdSwgZXQgcmlkYWRlIGFydiBrbGFwaWtzIHRlaXNlIGFuZG1lc3Rpa3VnYS4gU2VsbGVwIGxlaWRzaW1lIGFsZ3VzZXMgVG90YWxDb3VudGkgam1zIHN1bW1lZXJpdHVkIHRhYmVsaSwga3VuYSB2YWt0c2lpbiB0YWJlbGlzIG9uIGlnYXMgbWFha29ubmFzIGVyaW5ldmF0ZSB2YW51c2VncnVwcGlkZSByZWFkIGptcy4gU2VlZ2EgaWdhbCBtYWFrb25uYWwgbWl0dSByaWRhLgoKYGBge3J9CgptYWFrb25kICU+JSAKICBsZWZ0X2pvaW4odmFrdHNpaW4gJT4lIHJlbmFtZShNTklNSSA9IENvdW50eSkpICU+JSAKICBnZ3Bsb3QoKSArCiAgIGdlb21fc2YoYWVzKGZpbGwgPSBUb3RhbENvdW50KSkKYGBgCgojIyMjIMOcbGVzYW5uZQoKLSAgIEpvb25pc3RhIHbDpHJ2aXR1ZCBrYWFydCBncmFhZmlrIGdydXBpICLDvGxlIDcwIiAoTSArTiksIHZha3RzaW5lZXJpdHV0ZSBwcm90c2VuZGkga29odGEuCgpgYGB7cn0KdjIgPSB2YWt0c2lpbiAlPiUKICBmaWx0ZXIoQWdlR3JvdXAgPT0gIsO8bGUgNzAiKSAlPiUgCiAgZ3JvdXBfYnkoQ291bnR5KSAlPiUgCiAgc3VtbWFyaXplKAogICAgVG90YWxDb3VudCA9IHN1bShUb3RhbENvdW50KSwKICAgIFRvdGFsUG9wdWxhdGlvbiA9IHN1bShQb3B1bGF0aW9uKQogICkgCgp2MgoKdm0yID0gbWFha29uZCAlPiUgCiAgbGVmdF9qb2luKHYyICU+JSByZW5hbWUoTU5JTUkgPSBDb3VudHkpKQoKZ2dwbG90KHZtMikgKyAKICBnZW9tX3NmKGFlcyhmaWxsID0gVG90YWxDb3VudC9Ub3RhbFBvcHVsYXRpb24pKSArCiAgZ2VvbV9zZl90ZXh0KGFlcyhsYWJlbCA9IHJvdW5kKFRvdGFsQ291bnQvVG90YWxQb3B1bGF0aW9uLCAzKSksIGNvbG9yID0gIndoaXRlIikgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQoIlByb3BWYWNjaW5hdGVkIiwgbG93ID0gImxpZ2h0Z3JlZW4iLCBoaWdoID0gImRhcmtncmVlbiIpICsKICB0aGVtZV92b2lkKCkKYGBgCgoKIyMgR2VvZ3JhYWZpbGlzdGUgYW5kbWV0ZSBsZWlkbWluZQoKIyMjIE1hYWFtZXRpIEdlb3BvcnRhYWwKCkVlc3RpIGtvaHRhIG9uIHBhbGp1IGF2YWFuZG1laWQgc2FhZGF2YWwgTWFhYW1ldGkgR2VvcG9ydGFhbGlzLiBWZWt0b3JrdWp1bCBhbmRtZXRlbGUgdmlpZGF0YWtzZSwga3VpIFNIUCBmb3JtYWFkaXMgYW5kbWV0ZWxlLiBWYWF0YW1lIG7DpGl0ZWtzIGxlaGVsZSA8aHR0cHM6Ly9nZW9wb3J0YWFsLm1hYWFtZXQuZWUvZXN0L1J1dW1pYW5kbWVkL0Vlc3RpLXRvcG9ncmFhZmlhLWFuZG1la29ndS9MYWFkaS1FVEFLLWFuZG1lZC1hbGxhLXA2MDkuaHRtbD4KCkphIGxhZW1lIHNlYWx0IGFsbGEgU0hQIGZhaWxpIHRlaG5vdsO1cmt1ZGUga29odGEuCgpgYGB7cn0KdGVobm8gPSBzdF9yZWFkKCJFVEFLX0Vlc3RpX1NIUF90ZWhub3Zvcmd1ZC9FXzYwMV9lbGVrdHJpbGlpbl9qLnNocCIpCgp0ZWhubwoKdGVobm8gJT4lIAogIGdncGxvdCgpICsKICAgIGdlb21fc2YoKQpgYGAKCiMjIyBOYXR1cmFsIEVhcnRoCgpLdWkgbWUgdGFoYW1lIGpvb25pc3RhZGEgc3V1cmVtYWlkIGthYXJ0ZSBrdWkgRWVzdGkga29odGEsIG7DpGl0ZWtzIG1hYWlsbWFqYW8gdsO1aSBtYWFpbG1hIHRhc2VtZWwsIHNpaXMgb24gaGVha3MgYWxsaWtha3MgTmF0dXJhbCBFYXJ0aCBhbmRtZWJhYXMsIGt1cyBvbiBtYWFpbG1hIHJpaWtpZGUga29odGEga8OkaXYgc3RhdGlzdGlrYSBqYSBuZW5kZSBrdWp1ZmFpbGlkIG11Z2F2YWx0IGtva2t1IHBhbmR1ZC4gUi1zIHNhYWIgc2lubmEgbGlnaSBwYWtldGlnYSBgcm5hdHVyYWxlYXJ0aGAgbmluZyBzZWxsZSBmdW5rdHNpb29uaWdhIGBuZV9jb3VudGlyZXNgLgoKYGBge3J9CmNvdW50cmllcyA9IG5lX2NvdW50cmllcyhyZXR1cm5jbGFzcyA9ICJzZiIpCgpjb3VudHJpZXMKCnZpZXcoY291bnRyaWVzKQoKZ2dwbG90KGNvdW50cmllcykgKwogIGdlb21fc2YoYWVzKGZpbGwgPSBpbmNvbWVfZ3JwKSkKCmNvdW50cmllcyAlPiUgCiAgZmlsdGVyKGNvbnRpbmVudCA9PSAiQWZyaWNhIikgJT4lCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZihhZXMoZmlsbCA9IGluY29tZV9ncnApKQpgYGAKClNlYWx0IHNhYWIga2EgdMOkcHNlbWF0IGFkbWluaXN0cmF0aWl2c2UgYWxhbWphb3R1c2UgaW5mb3Qga8Okc3VnYSBgbmVfc3RhdGVzYCwgbWlsbGVsZSBwZWFiIGFuZG1hIGFyZ3VtZW5kaWtzIGV0dGUgcmlpZ2kuIEVlc3RpIGtvaHRhIG9uIHNlZSBhbmRtZXN0aWsgbmF0dWtlIHbDpGlrZXNlIHJlc29sdXRzaW9vbmlnYSwga3VpZCBzdXVyZW1hdGUgcmlpa2lkZSBqYW9rcyBvbiB2w6RnYSBoZWEuCgpgYGB7cn0KbmVfc3RhdGVzKGNvdW50cnkgPSAiRXN0b25pYSIsIHJldHVybmNsYXNzID0gInNmIikKCm5lX3N0YXRlcyhjb3VudHJ5ID0gIkVzdG9uaWEiLCByZXR1cm5jbGFzcyA9ICJzZiIpICU+JSAKICBnZ3Bsb3QoKSArCiAgICBnZW9tX3NmKCkKCm5lX3N0YXRlcyhjb3VudHJ5ID0gIlVuaXRlZCBLaW5nZG9tIiwgcmV0dXJuY2xhc3MgPSAic2YiKSAlPiUgCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZigpCmBgYAoKIyMjIE9wZW4gU3RyZWV0IE1hcHMKCk9wZW4gU3RyZWV0IE1hcHMgKE9TTSkgb24gYXZhdHVkIHZhc3RlIEdvb2dsZSBNYXBzaWxlIG5pbmcgc2lzYWxkYWIga8O1aWt2w7VpbWFsaWtrdSBrYWFyZGltYXRlcmphbGkuIEluaW1lc2VkIMO8bGUgbWFhaWxtYSB0w6RpZW5kYXZhZCBzZWRhIHBpZGV2YWx0LCBuaWkgZXQgdGVndSBvbiBwaWRldmFzIGFyZW5ndXMgb2xldmEgYW5kbWViYWFzaWdhLiBJbmZvdCBvbiBzZWFsIGthdWdlbHQgcm9oa2VtIGt1aSBvbiBtw7Vpc3RsaWsga29ycmFnYSBvbWEgYXJ2dXRpc3NlIGxhYWRpZGEsIHNlZXTDtXR0dSB0dWxlYiBPU00gYW5kbWV0ZSBrYXN1dGFtaXNla3MgdGVoYSBww6RyaW5ndWlkIE9TTSBBUEktbGUgbWlzIHNhYWRhYiB0w6Rwc2VsdCB2YWphbGlrdWQgYW5kbWVkLiBPU00gQVBJIHbDpGxqYWt1dHN1bWluZSBqYSBzZWFsdCBzYWFidXZhdGUgYW5kbWV0ZSDDtWlnZXNzZSBmb3JtYWF0aSB0ZWlzZW5kYW1pbmUgb24gaW1wbGVtZW50ZWVyaXR1ZCBwYWtldGlzIGBvc21kYXRhYC4gU2VsbGVnYSB0w7bDtnRhbWlzZSBzw7xzdGVlbSBvbiBqw6RyZ21pbmUuICoqVmFhdGEgT1NNIHdpa2l0LCBldCBuw6RoYSwgbWlkYSBlcmluZXZhZCBkZWlmbml0c2lvb25pZCBqYSBuaW1lZCBhbmRtZXN0aWt1cyB0w6RoZW5kYXZhZCBqbmUqKgoKLSAgIEVzaXRla3MgdHVsZWIgZGVmaW5lZXJpZGEgw7xtYnJpdHNldiBrYXN0ICgqaS5rIGJvdW5kaW5nIGJveCopIG5laWxlIGFuZG1ldGVsZSwgbWlkYSB0YWhhbWUgYWxsYSBsYWFkaWRhLiBTZWRhIHNhYWIgdGVoYSBwYWtldGkgYG9zbWRhdGFgIGvDpHN1Z2EgYGdldGJiYCwgbWlsbGUgYXJndW1lbmRpa3MgdHVsZWIgcGFubmEgbWVpZCBodXZpdGF2IGtvaGFuaW1pIG1pbmdpcyBmb3JtYWFkaXMuIE7DpGl0ZWtzICJUYXJ0dSIsICJSYXBsYW1hYSIsICJIYWFiZXJzdGkiLgoKYGBge3J9CmdldGJiKCJOYXJ2YSIpCmBgYAoKLSAgIFRlaXNla3MgdHVsZWIga8Okc3VzIGBhZGRfb3NtX2ZlYXR1cmVgIGRlZmluZWVyaWRhIG1pcyBpbmZvdCBzb292aXRha3NlIHNhYWRhLiBLw7Vpa2lkZXN0IHRhYmVsaXRlc3Qgc2FhYiDDvGxldmFhdGUgZnVua3RzaW9vbmlnYSBhdmFpbGFibGVfZmVhdHVyZXMgamEga29ua3JlZXRzZSB0YWJlbGkgYWxhbWFqb3R1c3Rlc3QgYXZhaWxhYmxlX3RhZ3MKCmBgYHtyfQphdmFpbGFibGVfZmVhdHVyZXMoKSAlPiUgdGFpbCgpCgphdmFpbGFibGVfdGFncygid2F0ZXIiKQpgYGAKCi0gTcO1bmVkIGthc3VsaWt1bWFkIHRhYmVsaWQgb24KCiAgICAgICAgLSAgICJoaWdod2F5IiAtIGvDtWlrIHRlZWQgamEgc2lsbGFkCgogICAgICAgIC0gICAiYm91bmRhcnkiIC0gcGlpcmlkICh0YWcgImFkbWluaXN0cmF0aXZlIiBhbm5hYiBhbWV0bGlrdWQgcGlpcmlkCgogICAgICAgIC0gICAiYnVpbGRpbmciIC0ga8O1aWsgaG9vbmVkCgogICAgICAgIC0gICAid2F0ZXIiIC0ga8O1aWsgc2lzZXZlZWtvZ3VkOiBqw7VlZCwgasOkcnZlZCwgdGlpZ2lkCgotIEtvbG1hbmRha3MgdHVsZWIga8O1aWsgaW5mbyBhbGxhIGxhYWRpZGEuIFNlbGxla3Mgb24ga8Okc3VkIGBvc21kYXRhX3NmKCkgJT4lIHVubmFtZV9vc21kYXRhX3NmKClgLiBTZWUgcHJvdHNlc3MgdsO1aWIgYWVnYSB2w7V0dGEgamEgZWkgcHJ1dWdpIGlnYSBrb3JkIMO1bm5lc3R1ZGEuIFNpaXMgcHJvb3ZpZGEgdXVlc3RpLgoKLSAgIEzDtXB1a3Mgc2FhbWUgYW5kbWVzdGlrdSwgbWlzIG9uIGxpc3QgZXJpbmV2YXRlc3QgYHNmYCBmb3JtYWFkaXMgdGFiZWxpdGVzdCB2YXN0YXZhbHQgb2JqZWx0aXTDvMO8YmlsZS4gU2VsbGUgbGlzdGkgZWxlbWVuZGlkIG9uCgogICAgLSAgIGBvc21fcG9pbnRzYAoKICAgIC0gICBgb3NtX2xpbmVzYAoKICAgIC0gICBgb3NtX3BvbHlnb25zYAoKICAgIC0gICBgb3NtX211bHRpcG9pbnRzYAoKICAgIC0gICBgb3NtX211bHRpbGluZXNgCgogICAgLSAgIGBvc21fbXVsdGlwb2x5Z29uc2AKClRlZW1lIGzDpGJpIMO8aGUgbsOkaXRlCgpgYGB7cn0KdGVlZCA9IG9wcShnZXRiYigiVGFydHUga2Vza2xpbm4iKSkgJT4lIAogIGFkZF9vc21fZmVhdHVyZShrZXkgPSAiaGlnaHdheSIpICU+JSAKICBvc21kYXRhX3NmKCkgJT4lIAogIHVubmFtZV9vc21kYXRhX3NmKCkKCiNWYWF0YW1lLCBtaXMgaW5mb3JtYXRzaW9vbmkgb24gam9vbnRlbmEga3VqdXRhdHVkIGthYXJ0aWRlbAp0ZWVkJG9zbV9saW5lcwpgYGAKClNhYWRhdmF0ZXMgYW5kbWV0ZXMgb24gcGFsanUgbcO8cmEga3VuYSBvbiBhcnZlc3RhdHVkIGlnYXN1Z3VzdGUgdsO1aW1hbGlrZSBhbm5vdGF0c2lvb25pZGVnYSAoc2VlZ2Egb24gdGFiZWwgbGFpKSBqYSBvbiBrb2trdSBwYW5kdWQgcGFsanUgZXJpbnZhIGtsYXNzaWdhIHRlZXNpZC4gU2VldMO1dHR1IHRhc3ViIGFuZG1laWQgZW5uZSBqb29uaXN0YW1pc3QgZmlsdHJlZXJpZGEuIEhlYSDDvGxldmFhdGUgZXJpbmV2YXRlc3QgdGVlIHTDvMO8cGlkZXN0IHNhYWIgPGh0dHBzOi8vd2lraS5vcGVuc3RyZWV0bWFwLm9yZy93aWtpL0tleTpoaWdod2F5Pi4KCmBgYHtyfQp0ZWVkJG9zbV9saW5lcyAlPiUgCiAgZmlsdGVyKCEoaGlnaHdheSAlaW4lIGMoInBlZGVzdHJpYW4iLCAicGF0aCIsICJjeWNsZXdheSIsICJzZXJ2aWNlIiwgImZvb3R3YXkiKSkpICU+JSAKICBnZ3Bsb3QoKSArCiAgIGdlb21fc2YoKQpgYGAKClNhcm5hc2VsdCBzYWFiIGFsbGEgbGFhZGlkYSBhZG1pbmlzdHJhdGlpdnNlZCDDvGtzdXNlZC4gTmVlZCBhZ2EgdHVsZXZhZCBtaXRtZXMgdGFzYW5kaXMgKHJpaWssIG9zYXJpaWssIG1hYWtvbmQsIHZhbGQsIGvDvGxhLCAuLi4pIC4gTWlzIG9uIGFudHVkIHR1bm51c2VnYSBgYWRtaW5fbGV2ZWxgLiBFZXN0aSBwdWh1bCBvbiBgYWRtaW5fbGV2ZWxgIGphb3R1bnVkIHVtYmVzIGrDpHJnbWlzZWx0LgoKLSAgIDIgLSByaWlrCgotICAgNiAtIG1hYWtvbmQKCi0gICA3IC0gdmFsZAoKLSAgIDggLSBsaW5uCgotICAgOSAtIGvDvGxhZCwgbGlubmFvc2FkCgotICAgMTAgLSBhc3VtaWQKCmBgYHtyfQpwaWlyaWQgPSBvcHEoZ2V0YmIoIlRhbGxpbm4iKSkgJT4lIAogIGFkZF9vc21fZmVhdHVyZShrZXkgPSAiYm91bmRhcnkiLCB2YWx1ZSA9ICJhZG1pbmlzdHJhdGl2ZSIpICU+JSAKICBvc21kYXRhX3NmKCkgJT4lIAogIHVubmFtZV9vc21kYXRhX3NmKCkKCnBpaXJpZCRvc21fbXVsdGlwb2x5Z29ucyAlPiUgCiAgZmlsdGVyKGFkbWluX2xldmVsID09IDgpICU+JSAKICBnZ3Bsb3QoKSArCiAgICBnZW9tX3NmKCkKCnBpaXJpZCRvc21fbXVsdGlwb2x5Z29ucyAlPiUgCiAgZmlsdGVyKGFkbWluX2xldmVsID09IDkpICU+JSAKICBnZ3Bsb3QoKSArCiAgICBnZW9tX3NmKCkKCnBpaXJpZCRvc21fbXVsdGlwb2x5Z29ucyAlPiUgCiAgZmlsdGVyKGFkbWluX2xldmVsID09IDEwKSAlPiUgCiAgZ2dwbG90KCkgKwogICAgZ2VvbV9zZigpCmBgYAoKVMO1bWJhbWUgYWxsIGthIHZlZWtvZ3VkIGphIGpvb25pc3RhbWUgbmVlZCBrYWFyZGlsZS4gS3VuYSB2ZWVrb2d1ZCB0dWxldmFkIG5paSBqb29udGUsIHBvbMO8Z29uaWRlIGt1aSBtdWx0aXBvbMO8Z29uaWRlbmEsIHBlYW1lIG5laWQgam9vbmlzdGFtYSBrYSBtaXRtZXMga2loaXMuCgpgYGB7cn0KCnZlc2kgPSBvcHEoZ2V0YmIoIlRhcnR1IGtlc2tsaW5uIikpICU+JSAKICBhZGRfb3NtX2ZlYXR1cmUoa2V5ID0gIndhdGVyIikgJT4lIAogIG9zbWRhdGFfc2YoKSAlPiUgCiAgdW5uYW1lX29zbWRhdGFfc2YoKQoKZ2dwbG90KCkgKwogIGdlb21fc2YoY29sb3IgPSAibGlnaHRibHVlIiwgZGF0YSA9IHZlc2kkb3NtX2xpbmVzKSArCiAgZ2VvbV9zZihmaWxsID0gImxpZ2h0Ymx1ZSIsIGRhdGEgPSB2ZXNpJG9zbV9wb2x5Z29ucykgKwogIGdlb21fc2YoZmlsbCA9ICJsaWdodGJsdWUiLCBkYXRhID0gdmVzaSRvc21fbXVsdGlwb2x5Z29ucykKYGBgCgpOYWd1IG7DpGhhIG9uIHRpaHRpIHByb2JsZWVtaWtzLCBldCBvYmpla3RpZCB1bGF0dXZhZCBrYXVnZWxlIGFsZ2VzdCDDvG1icml0c2V2YXN0IGthc3Rpc3QgdsOkbGphIHNlZXTDtXR0dSB2w7VpYiBzZWRhIMO8bWJyaXRzZXZhIGthc3RpIGtvb3JkaW5hYWRpZCBhbmRhIGV0dGUga2EgZnVua3RzaW9vbmlkZWxlIGB4bGltYCBqYSBgeWxpbWAuCgpgYGB7cn0KYmIgPSBnZXRiYigiVGFydHUga2Vza2xpbm4iKQpnZ3Bsb3QoKSArCiAgZ2VvbV9zZihjb2xvciA9ICJsaWdodGJsdWUiLCBkYXRhID0gdmVzaSRvc21fbGluZXMpICsKICBnZW9tX3NmKGZpbGwgPSAibGlnaHRibHVlIiwgZGF0YSA9IHZlc2kkb3NtX3BvbHlnb25zKSArCiAgZ2VvbV9zZihmaWxsID0gImxpZ2h0Ymx1ZSIsIGRhdGEgPSB2ZXNpJG9zbV9tdWx0aXBvbHlnb25zKSArCiAgZ2VvbV9zZihkYXRhID0gdGVlZCRvc21fbGluZXMpICsKICB4bGltKGJiWzEsIF0pICsgI3RzZW50cmVlcmliIGthYXJkaSBuZW5kZXNzZSBwaWlyaWRlc3NlLCBtaXMgYmJbXSBhbm5hYgogIHlsaW0oYmJbMiwgXSkgCmBgYAoKIyMjIMOcbGVzYW5uZQoKLSAgIEpvb25pc3RhIFJha3ZlcmUga2FhcnQsIGt1cyBvbiBwZWFsIGhvb25lZCwgdGVlZCAodGVpc3QgdsOkcnZpIGt1aSBob29uZWQpIGphIGxpbm5hIHBpaXIgKHBha3NlbWFuYSwga3VpIG11dWQgam9vbmVkKS4gS8O1aWsgYW5kbWVkIHTDtW1iYSBPU00tc3QuIEt1aSBzYWFkIGtpaXJlbHQgdmFsbWlzIHByb292aSBlcmluZXZhaWQgdsO1aW1hbHVzaSBrYWFydGkgaWx1c2FtYWtzIHRlaGEuCgpgYGB7cn0KI2xpbm5hcGlpcmlkCmJiID0gZ2V0YmIoIlJha3ZlcmUiKQoKI0hvb25lZAp2X2hvb25lID0gb3BxKGJiKSAlPiUgCiAgYWRkX29zbV9mZWF0dXJlKGtleSA9ICJidWlsZGluZyIpICU+JSAKICBvc21kYXRhX3NmKCkgJT4lIAogIHVubmFtZV9vc21kYXRhX3NmKCkKCiNUZWVkCnZfdGVlZCA9IG9wcShiYikgJT4lIAogIGFkZF9vc21fZmVhdHVyZShrZXkgPSAiaGlnaHdheSIpICU+JSAKICBvc21kYXRhX3NmKCkgJT4lIAogIHVubmFtZV9vc21kYXRhX3NmKCkKCiNBZG1pbmlzdHJhdGlpdsO8a3N1c2VkCnZfYWRtaW4gPSBvcHEoYmIpICU+JSAKICBhZGRfb3NtX2ZlYXR1cmUoa2V5ID0gImJvdW5kYXJ5IiwgdmFsdWUgPSAiYWRtaW5pc3RyYXRpdmUiKSAlPiUgCiAgb3NtZGF0YV9zZigpICU+JSAKICB1bm5hbWVfb3NtZGF0YV9zZigpCgpnZ3Bsb3QoKSArIAogIGdlb21fc2YoZmlsbD0id2hpdGUiLCBjb2xvciA9IE5BLCBkYXRhID0gdl9ob29uZSRvc21fcG9seWdvbnMpKwogIGdlb21fc2YoY29sb3IgPSAiZ3JleTgwIiwgZGF0YSA9IHZfdGVlZCRvc21fbGluZXMpKwogIGdlb21fc2YoY29sb3IgPSAid2hpdGUiLCBzaXplID0gMiwgZmlsbCA9IE5BLCBkYXRhID0gdl9hZG1pbiRvc21fbXVsdGlwb2x5Z29ucyAlPiUgZmlsdGVyKGFkbWluX2xldmVsID09IDcpICU+JSBmaWx0ZXIobmFtZSA9PSAiUmFrdmVyZSBsaW5uIikpKwogIHhsaW0oYmJbMSxdKSsKICB5bGltKGJiWzIsXSkrCiAgdGhlbWVfdm9pZCgpKwogIHRoZW1lKHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImJsYWNrIikpCmBgYAoK